//============================================================================
// Copyright (C) 2013 Brett R. Jones
//
// Issued to public domain 2013
//
// brettjones1900@gmail.com
// http://www.p2panarchy.com
//============================================================================

#include <VxUtilLib/VxSktUtil.h>
#include "VxIPv4Address.h"

#include <string.h>
#ifdef WIN_PLATFORM
	#include "Winsock2.h"
	#include<Ws2tcpip.h>  
#else
	#include <netdb.h>
	#include <sys/socket.h> 
	#include <sys/types.h>
	#include <arpa/inet.h>
#endif

#define INET6_MAX_STR_LEN 65

//============================================================================
VxIPv4Address::VxIPv4Address()
: m_u32IPv4Addr(0)
{
}

//============================================================================
VxIPv4Address::VxIPv4Address( const char * pIpAddress )
: m_u32IPv4Addr(0)
{
	fromString( pIpAddress );
}

//============================================================================
VxIPv4Address::VxIPv4Address( U32 u32IpAddr )
{
	setIp( u32IpAddr );
}

//============================================================================
bool VxIPv4Address::isLoopBack()
{
	if( 0x7f000001 == getIPv4Address() )
	{
		return true;
	}
	return false;
}

//============================================================================
//! equal operator
VxIPv4Address& VxIPv4Address::operator=(const VxIPv4Address& oAddr) 
{
	if( this != &oAddr )
	{
		m_u32IPv4Addr = oAddr.m_u32IPv4Addr;
	}
	return *this;
}

//============================================================================
bool VxIPv4Address::operator != (const VxIPv4Address& oAddr)
{
	return (m_u32IPv4Addr != oAddr.m_u32IPv4Addr);
}

//============================================================================
bool VxIPv4Address::operator == (const VxIPv4Address& oAddr)
{
	return (m_u32IPv4Addr == oAddr.m_u32IPv4Addr);
}

//============================================================================
bool VxIPv4Address::isValid( void )
{
	return ( 0 != m_u32IPv4Addr );
}

//============================================================================
void VxIPv4Address::setToInvalid( void )
{
	m_u32IPv4Addr = 0;
}

//============================================================================
void VxIPv4Address::fromString( const char * pIpAddress )
{
	if( ( 0 == strlen(pIpAddress)) ||
		( 0 == strcmp("0.0.0.0", pIpAddress )) ||
		( 0 == strcmp("::", pIpAddress ) ) )
	{
		setToInvalid();
	}
	else
	{
		U32 u32Ip = inet_addr( pIpAddress );
		setIp( htonl( u32Ip ) );
	}
}


//============================================================================
U32 VxIPv4Address::getIPv4Address( void )
{
	return m_u32IPv4Addr;
}

//============================================================================
// note.. u32IPv4Addr must be in host order
void VxIPv4Address::setIp( U32 u32IPv4Addr )
{
	m_u32IPv4Addr = u32IPv4Addr;
}

//============================================================================
void VxIPv4Address::setIp( const char * pIp )
{
	fromString( pIp );
}

//============================================================================
void VxIPv4Address::toStdString( std::string& retIpAddress )
{
	char as8Buf[ INET6_MAX_STR_LEN ];
	as8Buf[0] = 0; 

	if( isValid() )
	{
		//inet_ntop(AF_INET, &u32Ip, as8Buf, sizeof( as8Buf ) );
		VxIPv4_ntop( &m_u32IPv4Addr, as8Buf, sizeof( as8Buf ), false );
		retIpAddress = as8Buf;
	}
	else
	{
		retIpAddress = "0.0.0.0";
	}
}

//============================================================================
std::string VxIPv4Address::toStdString( void )
{
	std::string retIpAddress;
	toStdString( retIpAddress );
	return retIpAddress;
}
